/*
 * GameServiceImpl.java
 *
 * Distributed Systems: Project 2
 *
 */

package unimelb.distSystems.communications;

import unimelb.distSystems.communications.CORBA.*;
import org.omg.CORBA.*;

public class GameServiceImpl extends GameServicePOA{
    private ORB orb;
    private GameServer server;

    public void setORB(ORB orb_val) {
        orb = orb_val;
    }

    public GameServiceImpl(GameServer s) {
        super();
        server = s;
    }


    public long createNewAccount(ServiceAccount account){
        UserAccount user = server.getAccountManager().addNewUser(account);
        if(user != null){
            return user.getUserID();
        }
        return -1;
    }

    public boolean validateUsername(String user){
        return !server.getAccountManager().exists(user);
    }

    public long login(ClientService callobj, String username, String password){
        ServiceAccount account = server.getAccountManager().login(callobj, username, password);
        if(account == null){
            return -1;
        }
        return account.userID;
    }

    public ServiceAccount getUser(long id){
        return server.getAccountManager().getUser(id);
    }

    public boolean logout(){
        // TODO...
        return true;
    }



    public long createRoom(ServiceMatchRoom room){
        MatchRoom newRoom = server.getRoomsManager().addNewMatchRoom(room);
        if(newRoom == null){
            return -1;
        }
        return newRoom.getMatchroom_id();
    }

    public ServiceMatchRoom getMatchRoom(long roomID){
        ServiceMatchRoom room = server.getRoomsManager().getServiceRoom(roomID);
        return room;
    }

    public ServiceMatchRoom[] getAllRooms(){
        return server.getRoomsManager().getRooms();
    }

    public ServiceMatchRoom[] searchRoom(String word){
        return server.getRoomsManager().searchRoom(word);
    }

    public boolean joinGame(long roomID, long playerID){
        MatchRoom room = server.getRoomsManager().getMatchRoom(roomID);
        Player player = new Player(server.getAccountManager().getUserAccount(playerID));
        player.setReady(false);
        player.setLogin(true);
        if(room.addPlayer(player)){
        	MatchRoom this_room = server.getRoomsManager().getMatchRoom(roomID);
        	ServiceMessage new_message = new ServiceMessage(playerID, 
        			server.getAccountManager().getUser(playerID).driverName, "[JOINED]");
        	this_room.addMessage(new_message);
            sendChattoClient(roomID);
            sendPlayerstoClient(roomID);
            return true;
        }
        return false;
    }

    public boolean leaveGame(long roomID, long playerID){
        MatchRoom room = server.getRoomsManager().getMatchRoom(roomID);
        if(room.removePlayer(playerID)){
        	ServiceMessage new_message = new ServiceMessage(playerID, 
        			server.getAccountManager().getUser(playerID).driverName, "[LEFT]");
        	room.addMessage(new_message);
            sendChattoClient(roomID);
            sendPlayerstoClient(roomID);
        	
        	//check if there is no more player in this room
        	if(room.getPlayers().size()<=0)
        		server.getRoomsManager().deleteRoom(roomID);
        		
            return true;
        }
        return false;
    }
    
    public String[] getChatMessages(long roomID){
        MatchRoom room = server.getRoomsManager().getMatchRoom(roomID);
        return room.getChatArray();
    }

    public void sendChatMessage(long roomID, ServiceMessage message){
        MatchRoom room = server.getRoomsManager().getMatchRoom(roomID);
        room.addMessage(message);
        sendChattoClient(roomID);
    }

    public void sendChattoClient(long roomID){
        server.getRoomsManager().replicateChat(roomID);
    }

    public ServicePlayer[] getPlayers(long roomID){
        MatchRoom room = server.getRoomsManager().getMatchRoom(roomID);
        return room.getPlayersArray();
    }

    public void sendPlayerstoClient(long roomID){
        server.getRoomsManager().replicatePlayers(roomID);
    }

    public void ready(long roomID, long playerID, int car){
        MatchRoom room = server.getRoomsManager().getMatchRoom(roomID);
        ServiceMessage new_message = new ServiceMessage(playerID, 
    			server.getAccountManager().getUser(playerID).driverName, "[READY]");
    	room.addMessage(new_message);
    	sendChattoClient(roomID);
        
        Player player = room.getPlayer(playerID);
        player.setSelectedCar(car);
        player.setReady(true);
        sendPlayerstoClient(roomID);
    }

    public void roomOpen(long roomID){
        MatchRoom room = server.getRoomsManager().getMatchRoom(roomID);
        room.resetReady();
        room.setRaceInProgress(false);
        sendPlayerstoClient(roomID);
    }
    
    public void start(long roomID){
        server.getRoomsManager().signalRaceStart(roomID);
    }

    public void mark(long roomID, long playerID){
        MatchRoom room = server.getRoomsManager().getMatchRoom(roomID);
        Player player = room.getPlayer(playerID);
        player.setMark(true);
        if(room.onYourMarks()){
            server.getRoomsManager().signalRaceGo(roomID);
        }
    }

    public void sendAction(long roomID, ServiceAction action){
        server.getRoomsManager().replicateAction(roomID, action);
    }

    public void sendWin(long roomID, long winnerID){
        server.getRoomsManager().callOnLoosers(roomID, winnerID);
        roomOpen(roomID);
    }

}

